// run.C
//
// Template run macro for AliBasicTask.cxx/.h with example layout of
// physics selections and options, in macro and task.
//
// Author: Arvinder Palaha
//
class AliAnalysisGrid;

//______________________________________________________________________________
void run(
        const char* runtype = "proof", // local, proof or grid
        const char *gridmode = "full", // Set the run mode (can be "full", "test", "offline", "submit" or "terminate"). Full & Test work for proof
        const bool bMCtruth = 1, // 1 = MCEvent handler is on (MC truth), 0 = MCEvent handler is off (MC reconstructed/real data)
        const bool bMCphyssel = 1, // 1 = looking at MC truth or reconstructed, 0 = looking at real data
        const bool SystFlag = 0,  // 1 = running all tasks for systematics analysis, 0 = running only standard cuts
        const Long64_t nentries = 1234567890, // for local and proof mode, ignored in grid mode. Set to 1234567890 for all events.
        const Long64_t firstentry = 0, // for local and proof mode, ignored in grid mode
        const char *proofdataset = "/alice/data/LHC10e_000130517_p2",

        //path to dataset on proof cluster, for proof analysis
        //see for info
        //root[]TProof::Open("skaf.saske.sk")
        //root[]gProof->ShowDataSets()
        //and look at http://alimonitor.cern.ch/configuration/
        //
        //Good datasets on cluster "skaf.saske.sk":
        //"/alice/data/LHC10h_000138275_p2", PbPb at 2760 GeV, 3,280,000 events
        //"/alice/data/LHC10h_000137366_p2", PbPb at 2760 GeV, 1,270,000 events

        //"/alice/data/LHC10e_000130517_p2",  pp  at  7 TeV, 5,809,071

        //"/alice/sim/LHC10d1_000117109"

        // caf: /alice/sim/LHC10e20_000130844|/alice/sim/LHC10e20_000130520|/default/kimb/sim_LHC10e20_000130158_ESDs|/alice/sim/LHC10e20_000128913

        const char *proofcluster = "alice-caf.cern.ch",

        //"skaf.saske.sk",
        //"alice-caf.cern.ch"
        //"kiaf.sdfarm.kr"
        // which proof cluster to use in proof mode

        const char *taskname = "LRC7TeV_PythiaShiftedWindows_1804" // sets name of grid generated macros


        )
{
    gEnv->SetValue("XSec.GSI.DelegProxy", "2");
    // check run type
    if(runtype != "local" && runtype != "proof" && runtype != "grid"){
        Printf("\n\tIncorrect run option, check first argument of run macro");
        Printf("\tint runtype = local, proof or grid\n");
        return;
    }
    Printf("%s analysis chosen",runtype);

    /*void configureTaskOutput (AliAnalysisTask* taskAnalysis, TString strPrefixName= "")
{
    if(!taskAnalysis)
    return;
    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr)
    {
    Error("configureTaskOutput", "No analysis manager to connect to.");
    return ;
    }

    if (!mgr->GetInputEventHandler())
    {
    Error("AddTaskAnalysis", "This task requires an input event handler");
    return ;
    }

}*/

    // load libraries
    gSystem->Load("libCore.so");
    gSystem->Load("libGeom.so");
    gSystem->Load("libVMC.so");
    gSystem->Load("libPhysics.so");
    gSystem->Load("libTree.so");
    gSystem->Load("libSTEERBase.so");
    gSystem->Load("libESD.so");
    gSystem->Load("libAOD.so");
    gSystem->Load("libANALYSIS.so");
    gSystem->Load("libANALYSISalice.so");

    // add aliroot indlude path
    gROOT->ProcessLine(Form(".include %s/include",gSystem->ExpandPathName("$ALICE_ROOT")));
    gROOT->SetStyle("Plain");

    // analysis manager
    AliAnalysisManager* mgr = new AliAnalysisManager(taskname);

    // create the alien handler and attach it to the manager
    AliAnalysisGrid *plugin = CreateAlienHandler(taskname, gridmode, proofcluster, proofdataset,bMCtruth,bMCphyssel);
    mgr->SetGridHandler(plugin);

    AliVEventHandler* esdH = new AliESDInputHandler();
    mgr->SetInputEventHandler(esdH);

    // mc event handler
    if(bMCtruth) {
        AliMCEventHandler* mchandler = new AliMCEventHandler();
        // Not reading track references
        mchandler->SetReadTR(kFALSE);
        mgr->SetMCtruthEventHandler(mchandler);
    }

    // === Physics Selection Task ===
    //
    // In SelectCollisionCandidate(), default is kMB, so the task UserExec()
    // function is only called for these events.
    // Options are:
    //    kMB             Minimum Bias trigger
    //    kMBNoTRD        Minimum bias trigger where the TRD is not read out
    //    kMUON           Muon trigger
    //    kHighMult       High-Multiplicity Trigger
    //    kUserDefined    For manually defined trigger selection
    //
    // Multiple options possible with the standard AND/OR operators && and ||
    // These all have the usual offline SPD or V0 selections performed.
    //
    // With a pointer to the physics selection object using physSelTask->GetPhysicsSelection(),
    // one can manually set the selected and background classes using:
    //    AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL")
    //    AddBGTriggerClass("+CINT1A-ABCE-NOPF-ALL");
    //
    // One can also specify multiple classes at once, or require a class to NOT
    // trigger, for e.g.
    //    AddBGTriggerClass("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL");
    //
    // NOTE that manually setting the physics selection overrides the standard
    // selection, so it must be done in completeness.
    //
    // ALTERNATIVELY, one can make the physics selection inside the task
    // UserExec().
    // For this case, comment out the task->SelectCol.... line,
    // and see AliBasicTask.cxx UserExec() function for details on this.


    gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
    AliPhysicsSelectionTask *physSelTask = AddTaskPhysicsSelection(bMCphyssel);
    if(!physSelTask) { Printf("no physSelTask"); return; }
    //AliPhysicsSelection *physSel = physSelTask->GetPhysicsSelection();
    //physSel->AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL");// #3119 #769");

    //create taskCentrality (for AA)
    /*gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
    AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
    //taskCentrality->SetPass(2); // remember to set the pass you are processing!!!
    configureTaskOutput( taskCentrality, "taskCentrality");*/


    // create default task
    gROOT->LoadMacro("AliAnalysisTaskLRC.cxx++g");
    AliAnalysisTaskLRC* taskLRC = new AliAnalysisTaskLRC(taskname);
    taskLRC->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

    //Standard track cuts for ESD analysis
    AliESDtrackCuts *cuts = new AliESDtrackCuts("Cuts","Cuts");
    cuts->SetMinNClustersTPC(80);
    cuts->SetMinNClustersITS(2);
    cuts->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cuts->SetRequireTPCRefit(kTRUE);
    cuts->SetRequireITSRefit(kTRUE);
    cuts->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cuts->SetMaxDCAToVertexXY(0.5);
    cuts->SetMaxDCAToVertexZ(0.5);
    cuts->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cuts->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop
    //cuts->SaveHistograms("fTrackCuts");

    taskLRC->SetTrackCuts(cuts);
    taskLRC->SetVtxDiamond(0.4, 0.4, 7.0);

    if(SystFlag)
    {
    // |Vertex Z position| < 3 cm_____________________________________________________________________
    AliAnalysisTaskLRC* taskVtx3 = new AliAnalysisTaskLRC(taskname);
    taskVtx3->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
    taskVtx3->SetTrackCuts(cuts);
    taskVtx3->SetVtxDiamond(0.4, 0.4, 3.0);

    // |Vertex Z position| < 5 cm_______________________________________________________________________
    AliAnalysisTaskLRC* taskVtx5 = new AliAnalysisTaskLRC(taskname);
    taskVtx5->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
    taskVtx5->SetTrackCuts(cuts);
    taskVtx5->SetVtxDiamond(0.4, 0.4, 5.0);

    // |Vertex Z position| < 10 cm_____________________________________________________________________
    AliAnalysisTaskLRC* taskVtx10 = new AliAnalysisTaskLRC(taskname);
    taskVtx10->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
    taskVtx10->SetTrackCuts(cuts);
    taskVtx10->SetVtxDiamond(0.4, 0.4, 10.0);

    //N of TPC clusters 40________________________________________________________________________
    AliAnalysisTaskLRC* taskTPC40 = new AliAnalysisTaskLRC(taskname);
    taskTPC40->SelectCollisionCandidates(AliVEvent::kMB);

    AliESDtrackCuts *cutsTPC40 = new AliESDtrackCuts("CutsTPC40","CutsTPC40");
    cutsTPC40->SetMinNClustersTPC(40);
    cutsTPC40->SetMinNClustersITS(2);
    cutsTPC40->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsTPC40->SetRequireTPCRefit(kTRUE);
    cutsTPC40->SetRequireITSRefit(kTRUE);
    cutsTPC40->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsTPC40->SetMaxDCAToVertexXY(0.5);
    cutsTPC40->SetMaxDCAToVertexZ(0.5);
    cutsTPC40->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsTPC40->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskTPC40->SetTrackCuts(cutsTPC40);
    taskTPC40->SetVtxDiamond(0.4, 0.4, 7.0);

    //N of TPC clusters 100________________________________________________________________________
    AliAnalysisTaskLRC* taskTPC100 = new AliAnalysisTaskLRC(taskname);
    taskTPC100->SelectCollisionCandidates(AliVEvent::kMB);

    AliESDtrackCuts *cutsTPC100 = new AliESDtrackCuts("CutsTPC100","CutsTPC100");
    cutsTPC100->SetMinNClustersTPC(100);
    cutsTPC100->SetMinNClustersITS(2);
    cutsTPC100->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsTPC100->SetRequireTPCRefit(kTRUE);
    cutsTPC100->SetRequireITSRefit(kTRUE);
    cutsTPC100->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsTPC100->SetMaxDCAToVertexXY(0.5);
    cutsTPC100->SetMaxDCAToVertexZ(0.5);
    cutsTPC100->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsTPC100->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskTPC100->SetTrackCuts(cutsTPC100);
    taskTPC100->SetVtxDiamond(0.4, 0.4, 7.0);

    //N of ITS clusters 0_________________________________________________________________________
    AliAnalysisTaskLRC* taskITS0 = new AliAnalysisTaskLRC(taskname);
    taskITS0->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

    AliESDtrackCuts *cutsITS0 = new AliESDtrackCuts("CutsITS0","CutsITS0");
    cutsITS0->SetMinNClustersTPC(80);
    cutsITS0->SetMinNClustersITS(0);
    cutsITS0->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsITS0->SetRequireTPCRefit(kTRUE);
    cutsITS0->SetRequireITSRefit(kTRUE);
    cutsITS0->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsITS0->SetMaxDCAToVertexXY(0.5);
    cutsITS0->SetMaxDCAToVertexZ(0.5);
    cutsITS0->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsITS0->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskITS0->SetTrackCuts(cutsITS0);
    taskITS0->SetVtxDiamond(0.4, 0.4, 7.0);

    //N of ITS clusters 4_________________________________________________________________________
    AliAnalysisTaskLRC* taskITS4 = new AliAnalysisTaskLRC(taskname);
    taskITS4->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

    AliESDtrackCuts *cutsITS4 = new AliESDtrackCuts("CutsITS4","CutsITS4");
    cutsITS4->SetMinNClustersTPC(80);
    cutsITS4->SetMinNClustersITS(4);
    cutsITS4->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsITS4->SetRequireTPCRefit(kTRUE);
    cutsITS4->SetRequireITSRefit(kTRUE);
    cutsITS4->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsITS4->SetMaxDCAToVertexXY(0.5);
    cutsITS4->SetMaxDCAToVertexZ(0.5);
    cutsITS4->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsITS4->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskITS4->SetTrackCuts(cutsITS4);
    taskITS4->SetVtxDiamond(0.4, 0.4, 7.0);

    //DCA to vetrex 0.1_________________________________________________________________________
    AliAnalysisTaskLRC* taskDCA01 = new AliAnalysisTaskLRC(taskname);
    taskDCA01->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

    AliESDtrackCuts *cutsDCA01 = new AliESDtrackCuts("CutsDCA01","CutsDCA01");
    cutsDCA01->SetMinNClustersTPC(80);
    cutsDCA01->SetMinNClustersITS(2);
    cutsDCA01->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsDCA01->SetRequireTPCRefit(kTRUE);
    cutsDCA01->SetRequireITSRefit(kTRUE);
    cutsDCA01->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsDCA01->SetMaxDCAToVertexXY(0.1);
    cutsDCA01->SetMaxDCAToVertexZ(0.1);
    cutsDCA01->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsDCA01->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskDCA01->SetTrackCuts(cutsDCA01);
    taskDCA01->SetVtxDiamond(0.4, 0.4, 7.0);

    //DCA to vetrex 2.0_________________________________________________________________________
    AliAnalysisTaskLRC* taskDCA20 = new AliAnalysisTaskLRC(taskname);
    taskDCA20->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

    AliESDtrackCuts *cutsDCA20 = new AliESDtrackCuts("CutsDCA01","CutsDCA01");
    cutsDCA20->SetMinNClustersTPC(80);
    cutsDCA20->SetMinNClustersITS(2);
    cutsDCA20->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsDCA20->SetRequireTPCRefit(kTRUE);
    cutsDCA20->SetRequireITSRefit(kTRUE);
    cutsDCA20->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsDCA20->SetMaxDCAToVertexXY(2.0);
    cutsDCA20->SetMaxDCAToVertexZ(2.0);
    cutsDCA20->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsDCA20->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskDCA20->SetTrackCuts(cutsDCA20);
    taskDCA20->SetVtxDiamond(0.4, 0.4, 7.0);

    //ITS TPC refit kFalse________________________________________________________________________
    AliAnalysisTaskLRC* taskRefitFalse = new AliAnalysisTaskLRC(taskname);
    taskRefitFalse->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

    AliESDtrackCuts *cutsRefitFalse = new AliESDtrackCuts("CutsRefitFalse","CutsRefitFalse");
    cutsRefitFalse->SetMinNClustersTPC(80);
    cutsRefitFalse->SetMinNClustersITS(2);
    cutsRefitFalse->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    cutsRefitFalse->SetRequireTPCRefit(kFALSE);
    cutsRefitFalse->SetRequireITSRefit(kFALSE);
    cutsRefitFalse->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    cutsRefitFalse->SetMaxDCAToVertexXY(0.5);
    cutsRefitFalse->SetMaxDCAToVertexZ(0.5);
    cutsRefitFalse->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    cutsRefitFalse->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

    taskRefitFalse->SetTrackCuts(cutsRefitFalse);
    taskRefitFalse->SetVtxDiamond(0.4, 0.4, 7.0);

    //TPC only track cuts____________________________________________________________________________
    AliAnalysisTaskLRC* taskTPConly = new AliAnalysisTaskLRC(taskname);
    taskTPConly->SelectCollisionCandidates(AliVEvent::kMB);
    taskTPConly->SetTrackCuts(AliESDtrackCuts::GetStandardTPCOnlyTrackCuts() );
    taskTPConly->SetVtxDiamond(0.4, 0.4, 7.0);

    //Standard ITS TPC track cuts kTRUE______________________________________________________________
    AliAnalysisTaskLRC* taskITSTPC = new AliAnalysisTaskLRC(taskname);
    taskITSTPC->SelectCollisionCandidates(AliVEvent::kMB);
    taskITSTPC->SetTrackCuts(AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE));
    taskITSTPC->SetVtxDiamond(0.4, 0.4, 7.0);

    //Standard ITS TPC track cuts kFALSE______________________________________________________________
    AliAnalysisTaskLRC* taskITSTPCfalse = new AliAnalysisTaskLRC(taskname);
    taskITSTPCfalse->SelectCollisionCandidates(AliVEvent::kMB);
    taskITSTPCfalse->SetTrackCuts(AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kFALSE));
    taskITSTPCfalse->SetVtxDiamond(0.4, 0.4, 7.0);

    //Standard ITS TPC track cuts kTRUE with Crossed Rows_____________________________________________
    AliAnalysisTaskLRC* taskITSTPCCrossedRows = new AliAnalysisTaskLRC(taskname);
    taskITSTPCCrossedRows->SelectCollisionCandidates(AliVEvent::kMB);
    taskITSTPCCrossedRows->SetTrackCuts(AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE,1));
    taskITSTPCCrossedRows->SetVtxDiamond(0.4, 0.4, 7.0);

    mgr->AddTask(taskVtx3);
    mgr->AddTask(taskVtx5);
    mgr->AddTask(taskVtx10);
    mgr->AddTask(taskTPC40);
    mgr->AddTask(taskTPC100);
    mgr->AddTask(taskITS0);
    mgr->AddTask(taskITS4);
    mgr->AddTask(taskDCA01);
    mgr->AddTask(taskDCA20);
    mgr->AddTask(taskRefitFalse);
    mgr->AddTask(taskTPConly);
    mgr->AddTask(taskITSTPC);
    mgr->AddTask(taskITSTPCfalse);
    mgr->AddTask(taskITSTPCCrossedRows);
    }


    mgr->AddTask(taskLRC);


    if (bMCtruth)
    {
        //create task MCtrue
        gROOT->LoadMacro("AliAnalysisTaskMCtrue.cxx++g");
        AliAnalysisTaskMCtrue* taskMCtrue = new AliAnalysisTaskMCtrue(taskname);
        taskMCtrue->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
        taskMCtrue->SetVtxDiamond(0.4, 0.4, 7.0);
        mgr->AddTask(taskMCtrue);
    }

    // set output root file name for different analysis
    TString outfilename = Form("list.%s.root",runtype);

    // create containers for input/output
    AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
    AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("StandardCuts", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);

    if(SystFlag)
    {
    AliAnalysisDataContainer *coutputVtx3 = mgr->CreateContainer("Vertex3", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputVtx5 = mgr->CreateContainer("Vertex5", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputVtx10 = mgr->CreateContainer("Vertex10", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputTPC40 = mgr->CreateContainer("TPC40", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputTPC100 = mgr->CreateContainer("TPC100", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputITS0 = mgr->CreateContainer("ITS0", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputITS4 = mgr->CreateContainer("ITS4", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputDCA01 = mgr->CreateContainer("DCA01", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputDCA20 = mgr->CreateContainer("DCA20", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputRefitFalse = mgr->CreateContainer("ITSTPCRefitFalse", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputTPConly = mgr->CreateContainer("TPConly", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputITSTPC = mgr->CreateContainer("StandardITSTPC", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputITSTPCfalse = mgr->CreateContainer("StandardITSTPCfalse", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    AliAnalysisDataContainer *coutputITSTPCCrossedRows = mgr->CreateContainer("StandardITSTPCCrossedRows", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    }

    if (bMCtruth)
    {
        AliAnalysisDataContainer *MCtrueOutput = mgr->CreateContainer("MCtrue", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    }

    // connect input/output
    mgr->ConnectInput(taskLRC, 0, cinput);
    mgr->ConnectOutput(taskLRC, 1, coutput1);

    if (SystFlag)
    {
    mgr->ConnectInput(taskVtx3, 0, cinput);
    mgr->ConnectOutput(taskVtx3, 1, coutputVtx3);

    mgr->ConnectInput(taskVtx5, 0, cinput);
    mgr->ConnectOutput(taskVtx5, 1, coutputVtx5);

    mgr->ConnectInput(taskVtx10, 0, cinput);
    mgr->ConnectOutput(taskVtx10, 1, coutputVtx10);

    mgr->ConnectInput(taskTPC40, 0, cinput);
    mgr->ConnectOutput(taskTPC40, 1, coutputTPC40);

    mgr->ConnectInput(taskTPC100, 0, cinput);
    mgr->ConnectOutput(taskTPC100, 1, coutputTPC100);

    mgr->ConnectInput(taskITS0, 0, cinput);
    mgr->ConnectOutput(taskITS0, 1, coutputITS0);

    mgr->ConnectInput(taskITS4, 0, cinput);
    mgr->ConnectOutput(taskITS4, 1, coutputITS4);

    mgr->ConnectInput(taskDCA01, 0, cinput);
    mgr->ConnectOutput(taskDCA01, 1, coutputDCA01);

    mgr->ConnectInput(taskDCA20, 0, cinput);
    mgr->ConnectOutput(taskDCA20, 1, coutputDCA20);

    mgr->ConnectInput(taskRefitFalse, 0, cinput);
    mgr->ConnectOutput(taskRefitFalse, 1, coutputRefitFalse);

    mgr->ConnectInput(taskTPConly, 0, cinput);
    mgr->ConnectOutput(taskTPConly, 1, coutputTPConly);

    mgr->ConnectInput(taskITSTPC, 0, cinput);
    mgr->ConnectOutput(taskITSTPC, 1, coutputITSTPC);

    mgr->ConnectInput(taskITSTPCfalse, 0, cinput);
    mgr->ConnectOutput(taskITSTPCfalse, 1, coutputITSTPCfalse);

    mgr->ConnectInput(taskITSTPCCrossedRows, 0, cinput);
    mgr->ConnectOutput(taskITSTPCCrossedRows, 1, coutputITSTPCCrossedRows);
    }

    if (bMCtruth)
    {
        mgr->ConnectInput(taskMCtrue, 0, cinput);
        mgr->ConnectOutput(taskMCtrue, 1, MCtrueOutput);
    }

    // enable debug printouts
    mgr->SetDebugLevel(2);
    if (!mgr->InitAnalysis()) return;
    mgr->PrintStatus();

    // start analysis
    Printf("Starting Analysis....");
    mgr->StartAnalysis(runtype,nentries,firstentry);
}

//______________________________________________________________________________
AliAnalysisGrid* CreateAlienHandler(const char *taskname, const char *gridmode, const char *proofcluster, const char *proofdataset, bool bMCtruth, bool bMCphyssel)
{
    AliAnalysisAlien *plugin = new AliAnalysisAlien();
    // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
    plugin->SetRunMode(gridmode);

    // Set versions of used packages
    plugin->SetAPIVersion("V1.1x");
    plugin->SetROOTVersion("v5-34-02-1");

    plugin->SetAliROOTVersion("v5-04-31-AN");
    //plugin->SetRootVersionForProof( "VO_ALICE@ROOT::v5-34-02" );

    // Declare input data to be processed.

    // Method 1: Create automatically XML collections using alien 'find' command.
    // Define production directory LFN
    if ( !bMCtruth && !bMCphyssel ) //working with real data sets
    {
        //_________________________________________________________________

        //pp 7 TeV

//        //plugin->SetGridDataDir("/alice/data/2010/LHC10e");
//        plugin->SetGridDataDir("/alice/data/2010/LHC10d");

//        // Set data search pattern
//        //plugin->SetDataPattern("*ESDs.root"); // THIS CHOOSES ALL PASSES
//        plugin->SetDataPattern("*ESDs/pass2/*ESDs.root"); // CHECK LATEST PASS OF DATA SET IN ALIENSH!!!

//        plugin->SetRunPrefix("000");
//        // ...then add run numbers to be considered
//        plugin->AddRunNumber(126078);
//        plugin->AddRunNumber(126082);
//        plugin->AddRunNumber(126088);
//        plugin->AddRunNumber(126090);
//        plugin->AddRunNumber(126158);

// additional LHC10d runs if needed:

//        125842
//        125849
//        125850
//        125855
//        126007
//        126073

        //____________________________________________________________________________


        //pp 0.9 TeV

        plugin->SetGridDataDir("/alice/data/2010/LHC10c");

        // Set data search pattern
        //plugin->SetDataPattern("*ESDs.root"); // THIS CHOOSES ALL PASSES
        plugin->SetDataPattern("*ESDs/pass3/*ESDs.root"); // CHECK LATEST PASS OF DATA SET IN ALIENSH!!!

        plugin->SetRunPrefix("000");
        plugin->AddRunNumber(118506);
        plugin->AddRunNumber(118518);
        plugin->AddRunNumber(118556);
        plugin->AddRunNumber(118558);
        plugin->AddRunNumber(118560);
        plugin->AddRunNumber(118561);

        //______________________________________________________________________


        //pp 2.76 TeV

//        plugin->SetGridDataDir("/alice/data/2011/LHC11a");

//        // Set data search pattern
//        //plugin->SetDataPattern("*ESDs.root"); // THIS CHOOSES ALL PASSES
//        plugin->SetDataPattern("*ESDs/pass3_with_SDD/*ESDs.root"); // CHECK LATEST PASS OF DATA SET IN ALIENSH!!!

//        plugin->SetRunPrefix("000");
//        plugin->AddRunNumber(146801);
//        plugin->AddRunNumber(146802);
//        //plugin->AddRunNumber(146803);
//        plugin->AddRunNumber(146804);
//        plugin->AddRunNumber(146805);
//        plugin->AddRunNumber(146806);

        //_________________________________________________________________________


    }
    else
    {
        //pp 7 TeV Pythia Perugia 0___________________________________________________


        plugin->SetGridDataDir("/alice/sim/LHC10f6a");
        plugin->SetDataPattern("*ESDs.root");

        // ...then add run numbers to be considered
        plugin->AddRunNumber(126078);
        plugin->AddRunNumber(126082);
        //plugin->AddRunNumber(126007);
        plugin->AddRunNumber(126088);
        //plugin->AddRunNumber(126090);
        //plugin->AddRunNumber(126158);

        //old LHC10e anchor runs:
        //plugin->SetGridDataDir("/alice/sim/LHC10e20");


        //pp 2.76 TeV Pythia Perugia 0_________________________________________________


//        plugin->SetGridDataDir("/alice/sim/2011/LHC11e3a_plus");
//        plugin->SetDataPattern("*ESDs.root");

//        plugin->AddRunNumber(146801);
//        plugin->AddRunNumber(146802);
//        plugin->AddRunNumber(146804);
//        plugin->AddRunNumber(146806);
//        //plugin->AddRunNumber(146805);


//        //pp 0.9 TeV Pythia Perugia 0________________________________________________

//        plugin->SetGridDataDir("/alice/sim/LHC10e13");
//        plugin->SetDataPattern("*ESDs.root");

//        plugin->AddRunNumber(118506);
//        //plugin->AddRunNumber(118518);
//        plugin->AddRunNumber(118556);
//        plugin->AddRunNumber(118558);
//        plugin->AddRunNumber(118560);
//        //plugin->AddRunNumber(118561);

    }


    plugin->SetNrunsPerMaster(1);
    plugin->SetOutputToRunNo();
    // comment out the next line when using the "terminate" option, unless
    // you want separate merged files for each run

    //MergeOutputs: ### Re-run with <MergeViaJDL> off to collect results after merging jobs are done ###
    plugin->SetMergeViaJDL();

    // Method 2: Declare existing data files (raw collections, xml collections, root file)
    // If no path mentioned data is supposed to be in the work directory (see SetGridWorkingDir())
    // XML collections added via this method can be combined with the first method if
    // the content is compatible (using or not tags)
    //   plugin->AddDataFile("tag.xml");
    //   plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");

    // Define alien work directory where all files will be copied. Relative to alien $HOME.
    plugin->SetGridWorkingDir(taskname);

    // Declare alien output directory. Relative to working directory.
    plugin->SetGridOutputDir("out"); // In this case will be $HOME/taskname/out

    // Declare the analysis source files names separated by blancs. To be compiled runtime
    // using ACLiC on the worker nodes.

    //DON'T FORGET TO INCLUDE ALL FILES!!!

    if ( !bMCtruth && !bMCphyssel ) //working with real data sets
    {
        plugin->SetAnalysisSource("AliAnalysisTaskLRC.cxx");
    }
    else
    {
        plugin->SetAnalysisSource("AliAnalysisTaskLRC.cxx AliAnalysisTaskMCtrue.cxx");
    }


    // Declare all libraries (other than the default ones for the framework. These will be
    // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.

    //DON'T FORGET TO INCLUDE ALL FILES!!!

    if ( !bMCtruth && !bMCphyssel ) //working with real data sets
    {
        plugin->SetAdditionalLibs("AliAnalysisTaskLRC.h AliAnalysisTaskLRC.cxx");
    }
    else
    {
        plugin->SetAdditionalLibs("AliAnalysisTaskLRC.h AliAnalysisTaskLRC.cxx AliAnalysisTaskMCtrue.h AliAnalysisTaskMCtrue.cxx");
    }

    // Declare the output file names separated by blancs.
    // (can be like: file.root or file.root@ALICE::Niham::File)
    // To only save certain files, use SetDefaultOutputs(kFALSE), and then
    // SetOutputFiles("list.root other.filename") to choose which files to save
    plugin->SetDefaultOutputs();
    //plugin->SetOutputFiles("list.root");

    // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
    plugin->SetAnalysisMacro(Form("%s.C",taskname));

    // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
    plugin->SetSplitMaxInputFileNumber(100);

    // Optionally modify the executable name (default analysis.sh)
    plugin->SetExecutable(Form("%s.sh",taskname));

    // set number of test files to use in "test" mode
    plugin->SetNtestFiles(10);

    // Optionally resubmit threshold.
    plugin->SetMasterResubmitThreshold(90);

    // Optionally set time to live (default 30000 sec)
    plugin->SetTTL(30000);

    // Optionally set input format (default xml-single)
    plugin->SetInputFormat("xml-single");

    // Optionally modify the name of the generated JDL (default analysis.jdl)
    plugin->SetJDLName(Form("%s.jdl",taskname));

    // Optionally modify job price (default 1)
    plugin->SetPrice(1);

    // Optionally modify split mode (default 'se')
    plugin->SetSplitMode("se");

    //----------------------------------------------------------
    //---      PROOF MODE SPECIFIC SETTINGS         ------------
    //----------------------------------------------------------
    // Proof cluster
    plugin->SetProofCluster(proofcluster);
    // Dataset to be used
    plugin->SetProofDataSet(proofdataset);
    // May need to reset proof. Supported modes: 0-no reset, 1-soft, 2-hard
    plugin->SetProofReset(0);
    // May limit number of workers
    plugin->SetNproofWorkers(0);
    // May limit the number of workers per slave
    plugin->SetNproofWorkersPerSlave(0);
    // May use a specific version of root installed in proof
    //plugin->SetRootVersionForProof("current");
    // May set the aliroot mode. Check http://aaf.cern.ch/node/83
    plugin->SetAliRootMode("default"); // Loads AF libs by default
    // May request ClearPackages (individual ClearPackage not supported)
    plugin->SetClearPackages(kFALSE);
    // Plugin test mode works only providing a file containing test file locations, used in "local" mode also
    plugin->SetFileForTestMode("files.txt"); // file should contain path name to a local directory containg *ESDs.root etc
    // Request connection to alien upon connection to grid
    plugin->SetProofConnectGrid(kFALSE);

    return plugin;
}

